package com.thz.houserental.domain.house;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.xuyanwu.spring.file.storage.FileStorageService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.thz.houserental.domain.reservation.Reservation;
import com.thz.houserental.domain.reservation.ReservationService;
import com.thz.houserental.domain.tenant.TenantService;
import com.thz.houserental.infrastructure.auth.AuthUtil;
import com.thz.houserental.infrastructure.exception.ForbiddenException;
import com.thz.houserental.infrastructure.exception.NotFoundException;
import com.thz.houserental.infrastructure.table.User;
import com.thz.houserental.infrastructure.web.service.UserService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class HouseServiceImpl extends ServiceImpl<HouseMapper, House> implements HouseService {
    private final ReservationService reservationService;
    private final FileStorageService fileStorageService;
    private final UserService userService;
    private final TenantService tenantService;

    public HouseServiceImpl(@Lazy ReservationService reservationService, 
                            FileStorageService fileStorageService, 
                            UserService userService, 
                            @Lazy TenantService tenantService) {
        this.reservationService = reservationService;
        this.fileStorageService = fileStorageService;
        this.userService = userService;
        this.tenantService = tenantService;
    }

    @Override
    public House addHouse(HouseDto house) {
        //获取登录用户id
        String currentUserId = AuthUtil.getCurrentUserId();

        House houseEntity = new House();
        BeanUtil.copyProperties(house, houseEntity);
        houseEntity.setLandlord(currentUserId);

        // 文件信息记录
        if (house.getImageUrls() != null) {
            String imagesUrl = String.join(";", house.getImageUrls());
            houseEntity.setImages(imagesUrl);
        }
        if (house.getMp4Urls() != null) {
            String mp4Url = String.join(";", house.getMp4Urls());
            houseEntity.setMp4s(mp4Url);
        }
        houseEntity.setOnline(1);
        this.save(houseEntity);
        return houseEntity;
    }

    @Override
    public void deleteHouse(String houseId) {
        checkExistById(houseId);

        House house = this.getById(houseId);
        // 检查删除权限
        if (house.getLandlord().equals(AuthUtil.getCurrentUserId())) {
            // 删除
            this.removeById(houseId);
            // 删除文件
            if (StrUtil.isNotEmpty(house.getMp4s())) {
                String[] mp4s = house.getMp4s().split(";");
                for (String mp4 : mp4s) {
                    if (fileStorageService.exists(mp4)) {
                        fileStorageService.delete(mp4);
                    }
                }
            }

            if (StrUtil.isNotEmpty(house.getImages())) {
                String[] images = house.getImages().split(";");
                for (String image : images) {
                    if (fileStorageService.exists(image)) {
                        fileStorageService.delete(image);
                    }
                }
            }
        } else {
            throw new ForbiddenException(10200);
        }
    }

    @Override
    public Page<HouseVo> queryPage(QueryWrapper<House> queryWrapper, Page<HouseVo> housePage) {
        String currentUserId = AuthUtil.getCurrentUserId();
        Page<HouseVo> houseVoPage = this.baseMapper.queryPage(currentUserId, queryWrapper, housePage);
        houseVoPage.getRecords().forEach(e -> {
            if(StrUtil.isEmpty(e.getLeaseTerm())) {
                e.setLeaseTerm("不限");
            }
            if(StrUtil.isEmpty(e.getType())) {
                e.setType("不限");
            }
            e.setMp4Urls(Arrays.asList(e.getMp4s().split(";")));
            e.setImageUrls(Arrays.asList(e.getImages().split(";")));
        });
        return houseVoPage;
    }

    @Override
    public void updateHouse(HouseDto houseDto) {
        House house = this.getById(houseDto.getId());
        if (house.getLandlord().equals(AuthUtil.getCurrentUserId())) {
            // 更新
            House houseEntity = new House();
            House originHouse = this.getById(houseDto.getId());

            BeanUtil.copyProperties(houseDto, houseEntity);
            houseEntity.setLandlord(house.getLandlord());

            if (houseDto.getMp4Urls() != null) {
                String mp4s = String.join((";"), houseDto.getMp4Urls());

                // 清理旧文件
                if (StrUtil.isNotEmpty(originHouse.getMp4s())) {
                    for (String mp4 : originHouse.getMp4s().split(";")) {
                        if (fileStorageService.exists(mp4) && this.deletable(mp4, houseDto.getMp4Urls())) {
                            fileStorageService.delete(mp4);
                        }
                    }
                }
                houseEntity.setMp4s(mp4s);
            }

            if (houseDto.getImageUrls() != null) {
                String images = String.join(";", houseDto.getImageUrls());

                // 清理旧文件
                if (StrUtil.isNotEmpty(originHouse.getImages())) {
                    for (String image : originHouse.getImages().split(";")) {
                        if (fileStorageService.exists(image) && this.deletable(image, houseDto.getImageUrls())) {
                            fileStorageService.delete(image);
                        }
                    }
                }
                houseEntity.setImages(images);
                this.saveOrUpdate(houseEntity);
            }
        } else {
            throw new ForbiddenException(10201);
        }

    }

    @Override
    public HouseVo getDetail(String houseId) {
        checkExistById(houseId);

        House house = this.getById(houseId);
        HouseVo houseVo = new HouseVo();
        BeanUtil.copyProperties(house, houseVo);

        if (StrUtil.isNotEmpty(house.getImages())) {
            List<String> images = Arrays.stream(house.getImages().split(";")).collect(Collectors.toList());
            houseVo.setImageUrls(images);
        }

        if (StrUtil.isNotEmpty(house.getMp4s())) {
            List<String> mp4s = Arrays.stream(house.getMp4s().split(";")).collect(Collectors.toList());
            houseVo.setMp4Urls(mp4s);
        }

        //获取房源喜欢数
        int likeNum = this.reservationService.getLikedUsers(house.getId()).size();
        //获取房源收藏数
        int collectNum = this.reservationService.getCollectUsers(house.getId()).size();

        User landlord = this.userService.getById(houseVo.getLandlord());
        houseVo.setLandlordNickName(landlord.getNickName());
        houseVo.setAvatar((landlord.getAvatar()));

        houseVo.setLikeNum(likeNum);
        houseVo.setCollectNum(collectNum);

        String currentUserId = AuthUtil.getCurrentUserId();

        QueryWrapper<Reservation> likedWrapper = new QueryWrapper<>();
        likedWrapper.lambda()
                .eq(Reservation::getUserId, currentUserId)
                .eq(Reservation::getHouseId, houseId);
                
        QueryWrapper<Reservation> collectedWrapper = new QueryWrapper<>();
        collectedWrapper.lambda()
                .eq(Reservation::getUserId, currentUserId)
                .eq(Reservation::getIsCollect, 1)
                .eq(Reservation::getHouseId, houseId);
        
        if (reservationService.count(likedWrapper) > 0) {
            houseVo.setIsLiked(true);
        }
        if (reservationService.count(collectedWrapper) > 0) {
            houseVo.setIsLiked(true);
            houseVo.setIsCollected(true);
        }
        return houseVo;
    }

    @Override
    public void offLine(String houseId) {
        this.checkExistById(houseId);
        
        House house = this.getById(houseId);
        house.setOnline(0);
        this.updateById(house);
    }

    @Override
    public void onLine(String houseId) {
        this.checkExistById(houseId);
        
        // 如果房屋存在租户则不允许上线
        this.tenantService.checkByHouseId(houseId, false);
        
        House house = this.getById(houseId);
        house.setOnline(1);
        this.updateById(house);
    }

    private void checkExistById(String houseId) {
        if (this.getById(houseId) == null) {
            throw new NotFoundException(10202);
        }
    }

    /**
     * 判断某个旧文件是否存在在新文件列表中，如果存在则不能删
     */
    private boolean deletable(String oldFile, List<String> newFiles) {
        if (StrUtil.isNotEmpty(oldFile) && ArrayUtil.isNotEmpty(newFiles)) {
            for (String newFile : newFiles) {
                if (newFile.equals(oldFile)) {
                    return false;
                }
            }
        }
        return true;
    }

}
